﻿using GACore;
using System;
using System.Text;

namespace NQueensProblem
{
	public class NQueensProblem : Problem
	{
		private int vectorLength;

		public NQueensProblem(int vectorLength)
		{
			this.vectorLength = vectorLength;
		}

		protected override Vector[] CreateInitialPopulation()
		{
			Vector<int>[] population = new Vector<int>[preferences.PopulationCount];
			for (int i = 0; i < preferences.PopulationCount; i++)
			{
				population[i] = CreateRandomVector();
			}
			return population;
		}

		private Vector<int> CreateRandomVector()
		{
			Vector<int> vector = new Vector<int>(vectorLength, preferences.FitnessProperties, preferences.CrossoverProperties);

			for (int i = 0; i < vectorLength; i++)
			{
				vector[i] = random.Next(vectorLength);
			}
			return vector;
		}

		protected override double ComputeFitnessIndividual(Vector vector)
		{
			int beatCount = 0;
			for (int i = 0; i < vector.Length; i++)
			{
				for (int j = i + 1; j < vector.Length; j++)
				{
					if (CanBeat((Vector<int>)vector, i, j))
					{
						beatCount++;
					}
				}
			}
			return beatCount;
		}

		private bool CanBeat(Vector<int> vector, int leftColumn, int rightColumn)
		{
			return vector[leftColumn] == vector[rightColumn] || rightColumn - leftColumn == Math.Abs(vector[leftColumn] - vector[rightColumn]);
		}

		public override string GetProblemName()
		{
			return "N-Damen-Problem";
		}

		public override string GetProblemRepresentation()
		{
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < vectors.Length; i++)
			{
				sb.Append("Vektor");
				sb.AppendLine(i.ToString());

				Vector<int> vector = (Vector<int>)vectors[i];
				for (int j = 0; j < vector.Length; j++)
				{
					foreach (var elem in vector.Elements)
					{
						sb.Append(elem == j ? " D" : " X");
					}
					sb.AppendLine();
				}
				sb.AppendLine();
			}
			return sb.ToString();
		}
	}
}
